#!/bin/bash
# This tool is used to verify folders critical to ZoneMinder exist and have the right permissions.
# It will also create symlinks when necessary. It can use an existing content folder or create a new one.

# Set the content dir default to be the one supplied to cmake
ZM_PATH_CONTENT="@ZM_CONTENTDIR@"

# Set the zoneminder log dir default to be the one supplied to cmake
ZM_LOGDIR="@ZM_LOGDIR@"

# Set the zoneminder temp dir default to be the one supplied to cmake
ZM_TMPDIR="@ZM_TMPDIR@"

echo "*** This bash script creates the necessary symlinks for the zoneminder content"
echo "*** It can use an existing content folder or create a new one"
echo "*** For usage: use -h"
echo "*** The default content directory is: $ZM_PATH_CONTENT"
echo "*** The default log directory is: $ZM_LOGDIR"
echo "*** The default temp directory is: $ZM_TMPDIR"
echo ""

usage()
{
cat <<EOF
Usage: $0 [-q] [-o] [-z zm.conf] [-w WEB DIRECTORY] [-l LOG DIRECTORY] [-t TMP DIRECTORY] [CONTENT DIRECTORY]

OPTIONS:
   -h      Show this message and quit
   -z      ZoneMinder configuration file
   -w      Override the web directory from zm.conf
   -q      Quick mode. Do not change ownership recursively.
   -l      Override the zm log folder location
   -t      Override the zm temp folder location
   -o      Enable old legacy symlinks inside ZoneMinder's webroot folder

If the -w option is not used to specify the path to the web directory,
the script will use the path from zoneminder's configuration file.
If the -z option is used, the argument will be used instead of zm.conf
Otherwise, it will attempt to read zm.conf from the local directory.
If that fails, it will try from /etc/zm.conf

Newer versions of ZoneMinder no longer require symlinks to the events and
images folders inside the zm webroot. Indeed this is a security risk, and
$0 will no longer create these unless the -o option is specified.

EOF
}

while getopts "hz:w:q:l:t:o" OPTION
do
     case $OPTION in
         h)
             usage
             exit 50
             ;;
         z)
             ZM_CONFIG=$OPTARG
             ;;
         w)
             ZM_PATH_WEB_FORCE=$OPTARG
             ;;
         q)
             QUICK=1
             ;;
         l)
             ZM_LOGDIR_FORCE=$OPTARG
             ;;
         t)
             ZM_TMPDIR_FORCE=$OPTARG
             ;;
         o)
             LEGACY=1
             ;;
     esac
done
shift $(( OPTIND - 1 ))

# Lets check that we are root
if [ "$(id -u)" != "0" ]; then
	echo "Error: This script needs to run as root."
	exit 1
fi

# Check if zm.conf was supplied as an argument and that it exists
if [[ -n "$ZM_CONFIG" && ! -f "$ZM_CONFIG" ]]; then
	echo "The zoneminder configuration file $ZM_CONFIG does not exist!"
	exit 40
fi

# Load zm.conf
for zmconf in "$ZM_CONFIG" ./zm.conf /etc/zm.conf /etc/zoneminder/zm.conf; do
	if [[ -f "$zmconf" ]]; then
		echo "Using $zmconf"
		source "$zmconf"
		# remove filename from path
		zmconf2="${zmconf%/*}"
		# source conf.d
		for i in $(find "${zmconf2}/conf.d" -name \*.conf |sort); do . "$i"; done;
		break
	fi
done

if [[ -z "$zmconf2" ]]; then
	echo -e "Failed locating zoneminder configuration file (zm.conf)\nUse the -z option to specify the full path to the zoneminder configuration file"
	exit 45
fi

# Override the web directory path from zm.conf
if [ -n "$ZM_PATH_WEB_FORCE" ]; then
	ZM_PATH_WEB="$(readlink -f $ZM_PATH_WEB_FORCE)"
fi

# Override the log directory path
if [ -n "$ZM_LOGDIR_FORCE" ]; then
	ZM_LOGDIR="$(readlink -f $ZM_LOGDIR_FORCE)"
fi

# Override the tmp directory path
if [ -n "$ZM_TMPDIR_FORCE" ]; then
	ZM_TMPDIR="$(readlink -f $ZM_TMPDIR_FORCE)"
fi

# Override the default content path
if [[ -n "$@" ]]; then
	ZM_PATH_CONTENT="$(readlink -f $@)"
fi

# Print some information
echo "Web folder       : $ZM_PATH_WEB"
echo "Content folder   : $ZM_PATH_CONTENT"
echo "Log folder       : $ZM_LOGDIR"
echo "Temp folder       : $ZM_TMPDIR"
echo ""

# Verify the web folder is a real directory
echo -n "Verifying the web folder is a directory... "
if [ -d "$ZM_PATH_WEB" ]; then
	echo "OK"
else
	echo "Failed"
	exit 2
fi

# Check if the content folder exists, and if not, create it
echo -n "Checking if the content folder exists... "
if [ -d "$ZM_PATH_CONTENT" ]; then
	echo "Yes"
else
	echo "No"
	echo -n "Creating the content folder... "
	mkdir "$ZM_PATH_CONTENT"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 3
	fi
fi

# Check if the log folder exists, and if not, create the entire folder including its parents
echo -n "Checking if the log folder exists... "
if [ -d "$ZM_LOGDIR" ]; then
	echo "Yes"
else
	echo "No"
	echo -n "Creating the log folder... "
	mkdir -p "$ZM_LOGDIR"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 4
	fi
fi

# Check if the temp folder exists, and if not, create the entire folder including its parents
echo -n "Checking if the temp folder exists... "
if [ -d "$ZM_TMPDIR" ]; then
	echo "Yes"
else
	echo "No"
	echo -n "Creating the temp folder... "
	mkdir -p "$ZM_TMPDIR"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 5
	fi
fi

# Check if the content/images folder exists, and if not, create it
echo -n "Checking if the images folder exists inside the content folder... "
if [ -d "$ZM_PATH_CONTENT/images" ]; then
	echo "Yes"
else
	echo "No"
	echo -n "Creating the images folder inside the content folder... "
	mkdir "$ZM_PATH_CONTENT/images"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 6
	fi
fi

# Check if the content/events folder exists, and if not, create it
echo -n "Checking if the events folder exists inside the content folder... "
if [ -d "$ZM_PATH_CONTENT/events" ]; then
	echo "Yes"
else
	echo "No"
	echo -n "Creating the events folder inside the content folder... "
	mkdir "$ZM_PATH_CONTENT/events"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 7
	fi
fi

if [ -d "$ZM_PATH_WEB/images" ]; then
	if [ -L "$ZM_PATH_WEB/images" ]; then
		echo -n "Unlinking current symlink for the images folder... "
		unlink "$ZM_PATH_WEB/images"
		if [ "$?" = "0" ]; then
			echo "OK"
		else
			echo "Failed"
			exit 35
		fi
	else
		echo "Existing $ZM_PATH_WEB/images is not a symlink. Aborting to prevent data loss"
		exit 10
	fi
fi

if [ -d "$ZM_PATH_WEB/events" ]; then
	if [ -L "$ZM_PATH_WEB/events" ]; then
		echo -n "Unlinking current symlink for the events folder... "
		unlink "$ZM_PATH_WEB/events"
		if [ "$?" = "0" ]; then
			echo "OK"
		else
			echo "Failed"
			exit 36
		fi
	else
		echo "Existing $ZM_PATH_WEB/events is not a symlink. Aborting to prevent data loss"
		exit 11
	fi
fi

if [ -n "$LEGACY" ]; then
    # Create the symlink for the images folder
    echo -n "Creating the symlink for the images folder... " 
    ln -s -f "$ZM_PATH_CONTENT/images" "$ZM_PATH_WEB/images"
    if [ "$?" = "0" ]; then
        echo "OK"
    else
        echo "Failed"
        exit 15
    fi

    # Create the symlink for the events folder
    echo -n "Creating the symlink for the events folder... " 
    ln -s -f "$ZM_PATH_CONTENT/events" "$ZM_PATH_WEB/events"
    if [ "$?" = "0" ]; then
        echo "OK"
    else
        echo "Failed"
        exit 16
    fi
fi

# change ownership for the images folder. do it recursively unless -q is used
if [ -n "$QUICK" ]; then
	echo -n "Changing ownership of the images folder to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
	chown ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_PATH_CONTENT/images"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 20
	fi
else
	echo -n "Changing ownership of the images folder recursively to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
	chown -R ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_PATH_CONTENT/images"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 21
	fi
fi

# change ownership for the events folder. do it recursively unless -q is used
if [ -n "$QUICK" ]; then
	echo -n "Changing ownership of the events folder to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
	chown ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_PATH_CONTENT/events"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 23
	fi
else
	echo -n "Changing ownership of the events folder recursively to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
	chown -R ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_PATH_CONTENT/events"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 24
	fi
fi

# change ownership for the log folder. do it recursively unless -q is used
if [ -n "$QUICK" ]; then
	echo -n "Changing ownership of the log folder to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
	chown ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_LOGDIR"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 25
	fi
else
	echo -n "Changing ownership of the log folder recursively to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
	chown -R ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_LOGDIR"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 26
	fi
fi

# change ownership for the temp folder. do it recursively unless -q is used
if [ -n "$QUICK" ]; then
	echo -n "Changing ownership of the temp folder to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
	chown ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_TMPDIR"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 27
	fi
else
	echo -n "Changing ownership of the temp folder recursively to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
	chown -R ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_TMPDIR"
	if [ "$?" = "0" ]; then
		echo "OK"
	else
		echo "Failed"
		exit 28
	fi
fi

# Change directory permissions for the images folder
echo -n "Changing permissions of the images folder to 775... "
chmod 775 "$ZM_PATH_CONTENT/images"
if [ "$?" = "0" ]; then
	echo "OK"
else
	echo "Failed"
	exit 30
fi

# Change directory permissions for the events folder
echo -n "Changing permissions of the events folder to 775... "
chmod 775 "$ZM_PATH_CONTENT/events"
if [ "$?" = "0" ]; then
	echo "OK"
else
	echo "Failed"
	exit 31
fi

# Change directory permissions for the log folder
echo -n "Changing permissions of the log folder to 775... "
chmod 775 "$ZM_LOGDIR"
if [ "$?" = "0" ]; then
	echo "OK"
else
	echo "Failed"
	exit 32
fi

# Change directory permissions for the temp folder
echo -n "Changing permissions of the temp folder to 775... "
chmod 775 "$ZM_TMPDIR"
if [ "$?" = "0" ]; then
	echo "OK"
else
	echo "Failed"
	exit 33
fi

# Link the CakePHP tmp folder to the zoneminder temp folder
echo -n "Linking CakePHP tmp folder to ${ZM_TMPDIR}... "
ln -sfT "$ZM_TMPDIR" "$ZM_PATH_WEB/api/app/tmp"
if [ "$?" = "0" ]; then
	echo "OK"
else
	echo "Failed"
	exit 40
fi

echo ""
echo "All done"
